﻿using Novell.Directory.Ldap;
using System;
using System.Collections.Generic;

namespace S2_Xxxx_XxxNetApi
{
    public class ADHelper
    {
        protected LdapConnection Connection;

        protected string[] AdPaths;

        protected string AdHost;

        protected C_Dept Org { get; set; }

        protected C_User User { get; set; }

        public bool ADConnect()
        {
            AdHost = "192.168.16.160";
            string adAdminUserName = "administrator";
            string adAdminPassword = "123456";
            AdPaths = new string[] { "OU=oec2003,DC=COM,DC=cn" };

            if ((string.IsNullOrEmpty(AdHost) || string.IsNullOrEmpty(adAdminUserName)) ||
                string.IsNullOrEmpty(adAdminPassword))
            {
                return false;
            }
            try
            {
                Connection = new LdapConnection();
                Connection.Connect(AdHost, LdapConnection.DEFAULT_PORT);
                Connection.Bind(adAdminUserName, adAdminPassword);
            }
            catch
            {
                return false;
            }

            return true;
        }

        public List<LdapEntry> GetRootEntries(string[] adPathes, string host)
        {
            List<LdapEntry> list = new List<LdapEntry>();
            foreach (string path in adPathes)
            {
                if (!string.IsNullOrEmpty(host))
                {
                    LdapEntry entry = Connection.Read(path);
                    list.Add(entry);
                }
            }
            return list;
        }

        public bool Sync()
        {
            ADConnect();

            if (Connection == null)
            {
                throw new Exception("AD连接错误，请确认AD相关信息配置正确!");
            }
            bool result = true;
            List<LdapEntry> entryList = this.GetRootEntries(AdPaths, AdHost);
            Org = new C_Dept();
            User = new C_User();
            C_Dept rootOrg = GetRootOrg();
            foreach (LdapEntry entry in entryList)
            {
                SyncDirectoryEntry(entry, rootOrg, entry);
            }

            return result;
        }

        private void SyncDirectoryEntry(LdapEntry rootEntry, C_Dept parentOrg, LdapEntry currentEntry)
        {
            List<LdapEntry> entryList = currentEntry.Children(Connection);
            foreach (LdapEntry entry in entryList)
            {
                if (entry.IsOrganizationalUnit())
                {
                    C_Dept org = this.SyncOrgFromEntry(rootEntry, parentOrg, entry);
                    this.SyncDirectoryEntry(rootEntry, org, entry);
                }
                else if (entry.IsUser())
                {
                    this.SyncUserFromEntry(rootEntry, parentOrg, entry);
                }
            }
        }

        private C_Dept SyncOrgFromEntry(LdapEntry rootEntry, C_Dept parentOrg, LdapEntry entry)
        {
            string orgId = entry.Guid().ToLower();
            C_Dept org = GetOrgById(orgId) as C_Dept;
            if (org != null)
            {
                if (entry.ContainsAttr("ou"))
                {
                    org.Name = entry.getAttribute("ou").StringValue + string.Empty;
                }

                //设置其他属性的值
                UpdateOrg(org);
                return org;
            }
            org = new C_Dept
            {
                ObjectID = orgId,
                ParentID = parentOrg.ObjectID,
            };

            //设置其他属性的值
            AddOrg(org);
            return org;
        }

        private C_User SyncUserFromEntry(LdapEntry rootEntry, C_Dept parentOrg, LdapEntry entry)
        {
            string userId = entry.Guid().ToLower();
            C_User user = GetUserById(userId);
            if (user != null)
            {
                user.ParentID = parentOrg.ObjectID;
                //设置其他属性的值
                UpdateUser(user);

                return user;
            }
            user = new C_User
            {
                ObjectID = userId,
                ParentID = parentOrg.ObjectID
            };
            //设置其他属性的值
            AddUser(user);
            return user;
        }


        public bool AddOrg(C_Dept org)
        {
            //AD和数据库操作,待实现
            return true;
        }
        public bool UpdateOrg(C_Dept org)
        {
            //AD和数据库操作,待实现
            return true;
        }
        public C_Dept GetRootOrg()
        {
            //获取根Org,待实现
            return new C_Dept();
        }
        public C_Dept GetOrgById(string id)
        {
            //根据Id获取Org,待实现
            return new C_Dept();
        }

        public bool AddUser(C_User user)
        {
            //AD和数据库操作,待实现
            return true;
        }
        public bool UpdateUser(C_User user)
        {
            //AD和数据库操作,待实现
            return true;
        }
        public C_User GetUserById(string id)
        {
            //AD和数据库操作,待实现
            return new C_User();
        }
    }
}